package com.ideaaedi.zoo.commonbase.component.tenant;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.ideaaedi.zoo.commonbase.context.DefaultZcProvider;
import lombok.Getter;

import java.util.concurrent.ConcurrentLinkedDeque;

/**
 * 数据可操作域holder
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
public final class TenantScopeHolder {
    
    /**
     * 会话级临时数据域值
     * <p>
     * TransmittableThreadLocal相关说明可参考{@link DefaultZcProvider#contextThreadLocal}注释
     * </p>
     */
    @Getter
    public static final ThreadLocal<ConcurrentLinkedDeque<TenantScope>> SESSION_DATA_SCOPE_HOLDER = new TransmittableThreadLocal<>() {
        
        @Override
        protected ConcurrentLinkedDeque<TenantScope> initialValue() {
            return new ConcurrentLinkedDeque<>();
        }
        
        @Override
        public ConcurrentLinkedDeque<TenantScope> copy(ConcurrentLinkedDeque<TenantScope> parentValue) {
            return doCopy(parentValue);
        }
        
        @Override
        protected ConcurrentLinkedDeque<TenantScope> childValue(ConcurrentLinkedDeque<TenantScope> parentValue) {
            return doCopy(parentValue);
        }
        
        /**
         * (non-javadoc)
         */
        private ConcurrentLinkedDeque<TenantScope> doCopy(ConcurrentLinkedDeque<TenantScope> parentValue) {
            if (parentValue == null) {
                return new ConcurrentLinkedDeque<>();
            }
            return new ConcurrentLinkedDeque<>(
                    parentValue.stream().map(tenantScope -> {
                        if (tenantScope == null) {
                            return null;
                        }
                        return DefaultTenantScope.of(tenantScope.insertTenant(), tenantScope.readableTenants(),
                                tenantScope.modifiableTenants());
                    }).toList()
            );
        }
    };
}
